﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SW.EF.DAL
{
    public class Repository<TEntity,TKey> : IRepository<TEntity,TKey> where TEntity : class
    {
        #region Fields & Constructs & Dispose

        protected EFPermissionDBEntities Context = null;
        protected DbSet<TEntity> Entities
        {
            get
            {
                return Context.Set<TEntity>();
            }
        }

        public Repository()
        {
            Context = new EFPermissionDBEntities();
        }

        public Repository(EFPermissionDBEntities context)
        {
            Context = context;
        }

        public void Dispose()
        {
            if (Context != null)
                Context.Dispose();
        }

        #endregion

        public IQueryable<TEntity> Query()
        {
            return this.Entities.AsQueryable();
        }

        public IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate)
        {
            return this.Entities.Where(predicate).AsQueryable<TEntity>();
        }

        public Tuple<IQueryable<TEntity>, int> Filter(Expression<Func<TEntity, bool>> predicate, int page, int pageSize)
        {
            var query = this.Entities.Where(predicate);
            int count = query.Count();
            var list = query.Skip((page - 1) * pageSize).Take(pageSize);
            return new Tuple<IQueryable<TEntity>, int>(list, count);
        }

        public TEntity Find(TKey key)
        {
            return this.Entities.Find(key);
        }

        public TEntity Find(Expression<Func<TEntity, bool>> predicate)
        {
            return this.Entities.FirstOrDefault(predicate);
        }

        public int Count()
        {
            return this.Entities.Count();
        }

        public TEntity Save(TEntity model, bool isSave = true)
        {
            if (model == null) throw new Exception("model 不能为空!");
            this.Entities.Add(model);
            if (isSave)
                this.Context.SaveChanges();
            return model;
        }

        public TEntity Update(TEntity model, bool isSave = true)
        {
            if (model == null) throw new Exception("model 不能为空!");
            if (isSave)
                this.Context.SaveChanges();
            return model;
        }

        public int Delete(TEntity model, bool isSave = true)
        {
            if (model == null) throw new Exception("model 不能为空!");
            this.Entities.Remove(model);
            if (isSave)
                return this.Context.SaveChanges();
            return 0;
        }

        public int Delete(Expression<Func<TEntity, bool>> predicate, bool isSave = true)
        {
            int res = 0;
            var models = this.Entities.Where(predicate).ToList();
            if (models.Count > 0)
            {
                this.Entities.RemoveRange(models);
                if (isSave)
                    res = this.Context.SaveChanges();
            }
            return res;
        }
    }
}
